package com.wenyp;

import com.itextpdf.io.font.constants.StandardFonts;
import com.itextpdf.kernel.colors.Color;
import com.itextpdf.kernel.colors.ColorConstants;
import com.itextpdf.kernel.colors.DeviceCmyk;
import com.itextpdf.kernel.font.PdfFontFactory;
import com.itextpdf.kernel.geom.PageSize;
import com.itextpdf.kernel.pdf.PdfDocument;
import com.itextpdf.kernel.pdf.PdfPage;
import com.itextpdf.kernel.pdf.PdfWriter;
import com.itextpdf.kernel.pdf.canvas.PdfCanvas;
import com.itextpdf.kernel.pdf.canvas.PdfCanvasConstants;
import com.itextpdf.layout.Document;
import com.itextpdf.layout.element.Paragraph;
import org.junit.Before;
import org.junit.Test;

import javax.swing.text.StyleConstants;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;

/**
 * 底层操作使用
 * -406 0 m
 * 406 0 l
 * S
 * 移动到位置 ( X = -406 ; Y = 0 )，然后构建到位置 ( X = 406 ; Y = 0 ) 的路径；最后绘制这条线
 */
public class LowLevelPdf {

    public static String rootPath = "";

    @Before
    public void init(){
        rootPath = Paths.get("").toAbsolutePath().toString() + "/src/main/resources/";
        System.out.println("项目根路径: " + rootPath);
    }

    @Test
    public void test_draw_line() throws FileNotFoundException {
        String DEST = rootPath  + "/pdfFiles/test_draw_line.pdf";
        try(PdfDocument pdf = new PdfDocument(new PdfWriter(DEST));){
                PageSize ps = PageSize.A4.rotate();
                PdfPage page = pdf.addNewPage(ps);
                PdfCanvas canvas = new PdfCanvas(page);

                canvas.concatMatrix(1, 0, 0, 1, ps.getWidth() / 2, ps.getHeight() / 2);
                //Draw X axis
                canvas.moveTo(-(ps.getWidth() / 2 - 15), 0)
                        .lineTo(ps.getWidth() / 2 - 15, 0)
                        .stroke();
                //Draw X axis arrow
                canvas.setLineJoinStyle(PdfCanvasConstants.LineJoinStyle.ROUND)
                        .moveTo(ps.getWidth() / 2 - 25, -10)
                        .lineTo(ps.getWidth() / 2 - 15, 0)
                        .lineTo(ps.getWidth() / 2 - 25, 10).stroke()
                        .setLineJoinStyle(PdfCanvasConstants.LineJoinStyle.MITER);
                //Draw Y axis
                canvas.moveTo(0, -(ps.getHeight() / 2 - 15))
                        .lineTo(0, ps.getHeight() / 2 - 15)
                        .stroke();
                //Draw Y axis arrow
                canvas.saveState()
                        .setLineJoinStyle(PdfCanvasConstants.LineJoinStyle.ROUND)
                        .moveTo(-10, ps.getHeight() / 2 - 25)
                        .lineTo(0, ps.getHeight() / 2 - 15)
                        .lineTo(10, ps.getHeight() / 2 - 25).stroke()
                        .restoreState();
                //Draw X serif
                for (int i = -((int) ps.getWidth() / 2 - 61);
                     i < ((int) ps.getWidth() / 2 - 60); i += 40) {
                    canvas.moveTo(i, 5).lineTo(i, -5);
                }
                //Draw Y serif
                for (int j = -((int) ps.getHeight() / 2 - 57);
                     j < ((int) ps.getHeight() / 2 - 56); j += 40) {
                    canvas.moveTo(5, j).lineTo(-5, j);
                }

                Color grayColor = new DeviceCmyk(0.f, 0.f, 0.f, 0.875f);
                Color greenColor = new DeviceCmyk(1.f, 0.f, 1.f, 0.176f);
                Color blueColor = new DeviceCmyk(1.f, 0.156f, 0.f, 0.118f);

                canvas.setLineWidth(0.5f).setStrokeColor(blueColor);
                for (int i = -((int) ps.getHeight() / 2 - 57);
                     i < ((int) ps.getHeight() / 2 - 56); i += 40) {
                    canvas.moveTo(-(ps.getWidth() / 2 - 15), i)
                            .lineTo(ps.getWidth() / 2 - 15, i);
                }
                for (int j = -((int) ps.getWidth() / 2 - 61);
                     j < ((int) ps.getWidth() / 2 - 60); j += 40) {
                    canvas.moveTo(j, -(ps.getHeight() / 2 - 15))
                            .lineTo(j, ps.getHeight() / 2 - 15);
                }
                canvas.stroke();
        }
    }

    @Test
    public void test_draw_text() throws IOException {
        String DEST = rootPath + "/pdfFiles/test_draw_text.pdf";
        try (PdfDocument pdf = new PdfDocument(new PdfWriter(DEST));) {
            PageSize ps = PageSize.A4.rotate();
            PdfPage page = pdf.addNewPage(ps);
            PdfCanvas canvas = new PdfCanvas(page);

            List<String> text = new ArrayList();
            text.add("            Episode V      ");
            text.add("    THE EMPIRE STRIKES BACK  ");
            text.add("It is a dark time for the");
            text.add("Rebellion. Although the Death");
            text.add("Star has been destroyed,");
            text.add("Imperial troops have driven the");
            text.add("Rebel forces from their hidden");
            text.add("base and pursued them across");
            text.add("the galaxy.");
            text.add("Evading the dreaded Imperial");
            text.add("Starfleet, a group of freedom");
            text.add("fighters led by Luke Skywalker");
            text.add("has established a new secret");
            text.add("base on the remote ice world");
            text.add("of Hoth...");

            int maxStringWidth = 0;
            for (String fragment : text) {
                if (fragment.length() > maxStringWidth) maxStringWidth = fragment.length();
            }

            //Set black background
            canvas.rectangle(0, 0, ps.getWidth(), ps.getHeight())
                    .setColor(ColorConstants.BLACK, true)
                    .fill();

            //Replace the origin of the coordinate system to the top left corner
            canvas.concatMatrix(1, 0, 0, 1, 0, ps.getHeight());
            Color yellowColor = new DeviceCmyk(0.f, 0.0537f, 0.769f, 0.051f);
            float lineHeight = 5;
            float yOffset = -40;
            canvas.beginText()
                    .setFontAndSize(PdfFontFactory.createFont(StandardFonts.COURIER_BOLD), 1)
                    .setColor(yellowColor, true);
            for (int j = 0; j < text.size(); j++) {
                String line = text.get(j);
                float xOffset = ps.getWidth() / 2 - 45 - 8 * j;
                float fontSizeCoeff = 6 + j;
                float lineSpacing = (lineHeight + j) * j / 1.5f;
                int stringWidth = line.length();
                for (int i = 0; i < stringWidth; i++) {
                    float angle = (maxStringWidth / 2 - i) / 2f;
                    float charXOffset = (4 + (float) j / 2) * i;
                    canvas.setTextMatrix(fontSizeCoeff, 0,
                            angle, fontSizeCoeff / 1.5f,
                            xOffset + charXOffset, yOffset - lineSpacing)
                            .showText(String.valueOf(line.charAt(i)));
                }
            }
            canvas.endText();
        }
    }
}
